load("@bazel_skylib//rules:common_settings.bzl", "string_setting")
load("@gazelle//:def.bzl", "gazelle")
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
load("//ci/src/artifacts:upload.bzl", "upload_artifacts")

package(default_visibility = ["//visibility:public"])

# WARNING! .git is the directory, not a regular file! only consume it in your rules if you know how exactly bazel works and understand implications!
exports_files([
    ".git",
    "buf.yaml",
    "clippy.toml",
    "rustfmt.toml",
    "WORKSPACE.bazel",
    "mainnet-canister-revisions.json",
    "mainnet-icos-images.bzl",
])

alias(
    name = "buildifier",
    actual = "//bazel:buildifier",
)

alias(
    name = "ruff-format",
    actual = "//pre-commit:ruff-format",
)

alias(
    name = "protobuf-format",
    actual = "//pre-commit:protobuf-format",
)

alias(
    name = "shfmt-format",
    actual = "//pre-commit:shfmt-format",
)

alias(
    name = "rustfmt",
    actual = "@rules_rust//:rustfmt",
)

alias(
    name = "gen_rust_project",
    actual = "@rules_rust//tools/rust_analyzer:gen_rust_project",
)

# See https://github.com/bazelbuild/bazel-gazelle#running-gazelle-with-bazel
# gazelle:prefix github.com/dfinity/ic
# gazelle:proto disable
gazelle(
    name = "gazelle",
)

gazelle(
    name = "gazelle-update-repos",
    args = [
        "-from_file=go.mod",
        "-to_macro=go_deps.bzl%go_dependencies",
        "-prune",
    ],
    command = "update-repos",
)

alias(
    name = "gobin",
    actual = "@rules_go//go",
    visibility = ["//visibility:public"],
)

# Builds python dependencies. To update the lockfile:
# $ bazel run //:python-requirements.update
compile_pip_requirements(
    name = "python-requirements",
    timeout = "moderate",
    src = "requirements.in",
    requirements_txt = "requirements.txt",
)

test_suite(
    name = "single_large_node",  # the "_test" postfix is dropped on purpose since this target is meant for interactive use.
    tags = ["manual"],
    tests = ["//rs/tests/testnets:single_large_node"],
)

### Bitcoind

alias(
    name = "bitcoind",
    actual = select({
        "@bazel_tools//src/conditions:darwin_arm64": "@bitcoin_core_darwin_arm64//:bitcoind",
        "@bazel_tools//src/conditions:darwin_x86_64": "@bitcoin_core_darwin_x86//:bitcoind",
        "@bazel_tools//src/conditions:linux_aarch64": "@bitcoin_core_linux_aarch64//:bitcoind",
        "@bazel_tools//src/conditions:linux_x86_64": "@bitcoin_core_linux_x86//:bitcoind",
    }),
)

genrule(
    name = "dogecoind_stub",
    outs = ["dogecoind_stub.txt"],
    cmd = "echo 'Not supported on this platform.' > $@",
)

alias(
    name = "dogecoind",
    actual = select({
        "@bazel_tools//src/conditions:linux_x86_64": "@dogecoin_core_linux_x86//:dogecoind",
        "//conditions:default": "//:dogecoind_stub",
    }),
)

### ruff, python linter & formatter

alias(
    name = "ruff",
    actual = select({
        "@bazel_tools//src/conditions:linux_x86_64": "@ruff-x86_64-linux//:ruff",
        "@bazel_tools//src/conditions:darwin_arm64": "@ruff-aarch64-darwin//:ruff",
        "@bazel_tools//src/conditions:darwin_x86_64": "@ruff-x86_64-darwin//:ruff",
    }),
)

### rosetta-cli

alias(
    name = "rosetta-cli",
    actual = select({
        "@bazel_tools//src/conditions:linux_x86_64": "@rosetta-cli-x86_64-linux//:rosetta-cli-0.10.3-linux-amd64",
        "@bazel_tools//src/conditions:darwin_arm64": "@rosetta-cli-aarch64-darwin//:rosetta-cli-0.10.3-darwin-arm64",
        "@bazel_tools//src/conditions:darwin_x86_64": "@rosetta-cli-x86_64-darwin//:rosetta-cli-0.10.3-darwin-amd64",
    }),
)

### rclone, used for uploading artifacts to S3-compatible storage

alias(
    name = "rclone",
    actual = select({
        "@platforms//os:osx": "@rclone-x86_64-darwin//:rclone",  # No arm64 build for this version, use amd64 for now.
        "@bazel_tools//src/conditions:linux_x86_64": "@rclone-x86_64-linux//:rclone",
        "//conditions:default": "@platforms//:incompatible",
    }),
)

### trivy, used by ic-os for vulnerability scanning

alias(
    name = "trivy",
    actual = select({
        "@bazel_tools//src/conditions:linux_x86_64": "@trivy-x86_64-linux//:trivy",
        "@bazel_tools//src/conditions:darwin_arm64": "@trivy-aarch64-darwin//:trivy",
        "@bazel_tools//src/conditions:darwin_x86_64": "@trivy-x86_64-darwin//:trivy",
        "//conditions:default": "@platforms//:incompatible",
    }),
)

### dfx

alias(
    name = "dfx",
    actual = select({
        "@bazel_tools//src/conditions:darwin_x86_64": "@dfx-x86_64-darwin//:dfx",
        "@bazel_tools//src/conditions:darwin_arm64": "@dfx-aarch64-darwin//:dfx",
        "@bazel_tools//src/conditions:linux_x86_64": "@dfx-x86_64-linux//:dfx",
        "@bazel_tools//src/conditions:linux_aarch64": "@dfx-aarch64-linux//:dfx",
        "//conditions:default": "@platforms//:incompatible",
    }),
)

### pebble & pebble DNS, used in Boundary Nodes ACME testing

alias(
    name = "pebble",
    actual = select({
        "@bazel_tools//src/conditions:darwin_x86_64": "@pebble-x86_64-darwin//:pebble-bin",
        "@bazel_tools//src/conditions:darwin_arm64": "@pebble-aarch64-darwin//:pebble-bin",
        "@bazel_tools//src/conditions:linux_x86_64": "@pebble-x86_64-linux//:pebble-bin",
        "@bazel_tools//src/conditions:linux_aarch64": "@pebble-aarch64-linux//:pebble-bin",
        "//conditions:default": "@platforms//:incompatible",
    }),
)

alias(
    name = "pebble-challtestsrv",
    actual = select({
        "@bazel_tools//src/conditions:darwin_x86_64": "@pebble-challtestsrv-x86_64-darwin//:pebble-challtestsrv-bin",
        "@bazel_tools//src/conditions:darwin_arm64": "@pebble-challtestsrv-aarch64-darwin//:pebble-challtestsrv-bin",
        "@bazel_tools//src/conditions:linux_x86_64": "@pebble-challtestsrv-x86_64-linux//:pebble-challtestsrv-bin",
        "@bazel_tools//src/conditions:linux_aarch64": "@pebble-challtestsrv-aarch64-linux//:pebble-challtestsrv-bin",
        "//conditions:default": "@platforms//:incompatible",
    }),
)

### didc, used in fuzz testing

alias(
    name = "didc",
    actual = select({
        "@platforms//os:osx": "@didc-x86_64-darwin//file:didc",  # No arm64 build for this version, use amd64 for now.
        "@bazel_tools//src/conditions:linux_x86_64": "@didc-x86_64-linux//file:didc",
        "//conditions:default": "@platforms//:incompatible",
    }),
)

### shfmt, used to format bash code

alias(
    name = "shfmt",
    actual = select({
        "@bazel_tools//src/conditions:linux_x86_64": "@shfmt-x86_64-linux//file:shfmt",
        "@bazel_tools//src/conditions:darwin_arm64": "@shfmt-aarch64-darwin//file:shfmt",
        "@bazel_tools//src/conditions:darwin_x86_64": "@shfmt-x86_64-darwin//file:shfmt",
        "//conditions:default": "@platforms//:incompatible",
    }),
)

### Pocket IC

# The pocket-ic server binary. Use this as a test dependency if the test
# does not require a specific pocket-ic version (see ":pocket-ic-server-variant"
# for details).
# By default returns the pocket-ic server from the source tree to ensure
# consistency within the source tree. See 'pocket_ic_mainnet_test' for
# overrides.
alias(
    name = "pocket-ic-server",
    actual = select({
        ":pocket-ic-server-variant-mainnet": "//:pocket-ic-mainnet",
        ":pocket-ic-server-variant-head": "//rs/pocket_ic_server:pocket-ic-server",
        "//conditions:default": "//rs/pocket_ic_server:pocket-ic-server",
    }),
)

# A setting to switch between different variants of pocket-ic. The
# default pocket-ic variant/version (head) is the one as in the
# source tree.
string_setting(
    name = "pocket-ic-server-variant",
    build_setting_default = "head",
    visibility = ["//visibility:public"],
)

config_setting(
    name = "pocket-ic-server-variant-head",
    flag_values = {
        ":pocket-ic-server-variant": "head",
    },
)

# A "mainnet" variant of the pocket-ic server which represents a
# released version of pocket-ic.
config_setting(
    name = "pocket-ic-server-variant-mainnet",
    flag_values = {
        ":pocket-ic-server-variant": "mainnet",
    },
)

# The pocket-ic as released; use this for tests that need to ensure consistency
# with a release pocket-ic/replica.
genrule(
    name = "pocket-ic-mainnet",
    srcs = ["@pocket-ic-mainnet-gz//file"],
    outs = ["pocket-ic"],
    cmd = "gunzip -c $< > $@",
)

# Upload artifacts to the CDN
upload_artifacts(
    name = "upload-artifacts",
    testonly = True,
    inputs = [
        "//publish/binaries:bundle",
    ] + select({
        "@platforms//os:osx": [],
        "//conditions:default": [
            "//publish/binaries:bundle-legacy",  # avoid overwriting legacy artifacts
            "//publish/canisters:bundle",
            "//ic-os/guestos/envs/prod:bundle-update",
            "//ic-os/guestos/envs/dev:bundle-update",  # used by nested tests
            "//ic-os/hostos/envs/prod:bundle-update",
            "//ic-os/hostos/envs/dev:bundle-update",  # used by nested tests
            "//ic-os/setupos/envs/prod:bundle",
            "//ic-os/setupos/envs/dev:bundle",  # used by nested tests
            "//ic-os/guestos/envs/recovery:bundle-update",  # used for manual recovery
        ],
    }),
    visibility = ["//visibility:public"],
)

# Artifact uploader that can be run with `bazel run ... -- BUNDLE...`
upload_artifacts(
    name = "artifact-uploader",
)

# Test suite for super-fast tests (should only take a couple seconds to run).
test_suite(
    name = "insta_tests",
    tests = [
        "//bazel:buildifier_test",
        "//bazel:gazelle_test",
    ],
)
